package com.zb.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zb.entity.*;
import com.zb.extend.WorkNetworkExtend;
import com.zb.extend.WorkOrderExtend;
import com.zb.mobile.*;
import com.zb.result.PageUtil;
import com.zb.vo.*;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 工单表 服务类
 * </p>
 *
 * @author WEN
 * @since 2023-09-20
 */
public interface ZjWorkOrderService extends IService<ZjWorkOrder> {

    /**
     * 保存、修改工单
     *
     * @param loginInfo
     * @param isUserMobileOrder 是否客户报单移动端工单：false-不是，true-是
     * @param orderVo
     * @param orderGoodsVos
     * @return
     */
    Map<String, Object> save(AccounLoginInfo loginInfo, boolean isUserMobileOrder, OrderVo orderVo, List<OrderGoodsVo> orderGoodsVos);

    /**
     * 根据工单ID集合获取历史工单（编码的历史工单）
     *
     * @param workIds  工单ID
     * @param pageUtil
     * @return
     */
    Page<ZjWorkOrder> PageGetHistoryOrder(List<Long> workIds, PageUtil pageUtil);

    /**
     * 获取工单列表状态数量
     * @param custAccId 商家ID
     * @return
     */
    OrderStatusQtyVo getOrderListStatusQty(Long custAccId);

    /**
     * 获取工单列表ID数据
     * @param custAccId 商家ID
     * @param selectVo 搜索条件
     * @return
     */

    List<Long> getOrderListIdsByPageSearch(Long custAccId, OrderListSelectVo selectVo);

    /**
     * 获取工单归档列表ID数据
     * @param custAccId 商家ID
     * @param archivedListSearchVo 搜索条件
     * @return
     */
    List<Long> getOrderArchivedListIdsByPageSearch(Long custAccId, OrderArchivedListSearchVo archivedListSearchVo);

    /**
     * 根据商家ID获取归档工单的状态（已完成、已取消）数量
     * @param custAccId 商家ID
     * @return status 状态：4-已完成，5-已取消
     */
    long getOrderArchivedOrderStatusQty(Long custAccId, Integer status);

    /**
     * 获取工单列表数据
     * @param ids 工单ID集合
     * @param orderBy 排序
     * @return
     */
    List<WorkOrderExtend> getList(List<Long> ids, String orderBy);

    /**
     * 获取结算列表状态数量
     * @param custAccId 商家ID
     * @return
     */
    OrderSettlementStatusQtyVo getOrderSettlementStatusQty(Long custAccId);

    /**
     * 获取工单结算列表ID数据
     * @param custAccId 商家ID
     * @param searchVo 搜索条件
     * @return
     */
    List<Long> getOrderSettlementListIdsByPageSearch(Long custAccId, OrderSettlementListSearchVo searchVo);

    /**
     * 获取工单结算列表ID数据总记录数
     * @param custAccId 商家ID
     * @param searchVo 搜索条件
     * @return
     */
    long getOrderSettlementListCount(Long custAccId, OrderSettlementListSearchVo searchVo);

    /**
     * 获取工单结算列表数据
     * @param ids 工单ID集合
     * @param searchVo 排序条件
     * @return
     */
    List<WorkOrderExtend> getOrderSettlementList(List<Long> ids, OrderSettlementListSearchVo searchVo);

    /**
     * 获取工单列表数据
     * @param custAccId 商家ID
     * @param selectVo 搜索条件
     * @return
     */
    List<WorkOrderExtend> getOrderList(Long custAccId, OrderListSelectVo selectVo);

    /**
     * 获取工单列表数据总记录数
     * @param custAccId 商家ID
     * @param selectVo 搜索条件
     * @return
     */
    long getListCount(Long custAccId, OrderListSelectVo selectVo);

    /**
     * 获取工单归档列表数据总记录数
     * @param custAccId 商家ID
     * @param searchVo 搜索条件
     * @return
     */
    long getOrderArchivedListCount(Long custAccId, OrderArchivedListSearchVo searchVo);

    /**
     * 根据工单模块ID获取关联工单的模块ID
     * @param moduleIds
     * @return
     */
    List<Long> getRelationModuleIdByModuleIds(List<Long> moduleIds);

    /**
     * 根据工单ID集合获取处理结束的工单
     * @param workIds
     * @return
     */
    List<ZjWorkOrder> getHandlerEndOrderByIds(List<Long> workIds);

    /**
     * 根据客服ID获取客服处理中的工单数量
     * @param empIds
     * @return
     */
    List<EmpOrderCountVo> getEmpOrderCountByEmpIds(List<Long> empIds);

    /**
     * 根据客服ID查询最后完成工单的客服ID（根据客服分配策略查询熟客客服ID）
     *
     * @param empIds
     * @return
     */
    List<EmpOrderCountVo> getHistoryOrderLastEmpIdByEmpIds(List<Long> empIds);

    /**
     * 批量分配客服
     * @param loginInfo
     * @param workIds 工单ID
     * @param empId 客服ID
     */
    void dispatchOrderEmp(AccounLoginInfo loginInfo, List<Long> workIds, Long empId);

    /**
     * 检查工单是否处理中
     * @param workIds
     */
    void checkOrderHandlerStatus(List<Long> workIds);

    /**
     * 检查工单是否处理中
     * @param workId
     */
    void checkOrderHandlerStatus(Long workId);

    /**
     * 检查工单状态
     * @param workIds
     */
    void checkOrderStatus(List<Long> workIds);

    /**
     * 检查工单状态
     * @param workId
     */
    void checkOrderStatus(Long workId);

    /**
     * 检查工单事件
     * @param workIds
     */
    void checkOrderEvent(List<Long> workIds);

    /**
     * 检查工单事件
     * @param workId
     */
    void checkOrderEvent(Long workId);

    /**
     * 校验工单是否派单或派工
     * @param workIds
     */
    void checkIsDispatchOrder(List<Long> workIds);

    /**
     * 根据服务商ID获取所有工单数量
     * @param networkIds 服务商ID
     * @return
     */
    List<QtyVo> getTotalOrderByNetworkIds(List<Long> networkIds);

    /**
     * 根据服务商ID获取所有处理中工单数量
     * @param networkIds 服务商ID
     * @return
     */
    List<QtyVo> getServiceOrderByNetworkIds(List<Long> networkIds);


    /**
     * 获取服务商详情之工单明细列表
     * @param networkId 服务商ID
     * @param pageUtil
     * @return
     */
    List<ZjWorkOrder> getNetworkDetailOrderList(Long networkId, PageUtil pageUtil);

    /**
     * 获取服务商详情之工单明细列表
     * @param networkId 服务商ID
     * @return
     */
    long getNetworkDetailOrderListCount(Long networkId);

    /**
     * 根据服务商ID获取关联工单的服务商ID
     * @param networkIds 服务商ID
     * @return
     */
    List<Long> getRelationNetworkIdByNetworkId(List<Long> networkIds);


    /**
     * 根据工单ID获取关联的服务商
     * @param workIds 工单ID
     * @return
     */
    List<WorkNetworkExtend> getNetworkByWorkIds(List<Long> workIds);

    /**
     * 根据移动端报单工单列表关键词搜索
     * @param custAccId 商家ID
     * @param userId 客户ID
     * @param selectVo 搜索条件
     * @return
     */
    List<Long> getWorkIdByUserMobileSearch(Long custAccId, Long userId, UserOrderSelectVo selectVo);

    /**
     * 获取客户报单端工单列表
     * @param custAccId 商家ID
     * @param userId    客户ID
     * @param workIds   工单ID
     * @param selectVo  搜索条件
     * @return
     */
    List<WorkOrderExtend> getUserOrderList(Long custAccId, Long userId, List<Long> workIds, UserOrderSelectVo selectVo);

    /**
     * 获取客户报单端工单列表总记录数
     * @param custAccId 商家ID
     * @param userId 客户ID
     * @param workIds 工单ID
     * @param selectVo 搜索条件
     * @return
     */
    long getUserOrderListCount(Long custAccId, Long userId, List<Long> workIds, UserOrderSelectVo selectVo);

    /**
     * 获取移动端的历史工单
     * @param custAccId 商家ID
     * @param userId 客户ID
     * @param ids 工单ID
     * @param selectVo
     * @return
     */
    List<ZjWorkOrder> getUserMobileHistoryOrder(Long custAccId, Long userId, List<Long> ids, SelectVo selectVo);

    /**
     * 获取移动端的历史工单总记录数
     * @param custAccId 商家ID
     * @param userId 客户ID
     * @param ids 工单ID
     * @return
     */
    long getUserMobileHistoryOrderCount(Long custAccId, Long userId, List<Long> ids);


    /**
     * 获取服务商移动端工单报表(工单分析)
     * @param custAccId 商家ID
     * @param networkId 服务商ID
     * @param networkEmpId 服务商人员ID
     * @param manager 是否管理或负责人：false-不是，true-是
     */
    List<DateQtyVo> getNetworkMobileWeekCreateOrderStat(Long custAccId, Long networkId, Long networkEmpId, boolean manager);

    /**
     * 获取服务商移动端工单报表(工单分析)
     * @param custAccId 商家ID
     * @param networkId 服务商ID
     * @param networkEmpId 服务商人员ID
     * @param manager 是否管理或负责人：false-不是，true-是
     */
    List<DateQtyVo> getNetworkMobileWeekEndOrderStat(Long custAccId, Long networkId, Long networkEmpId, boolean manager);

    /**
     * 获取工单报表(工单类型占比)
     * @param networkId 服务商ID
     * @param selectVo 搜索条件对象
     * @return
     */
    List<QtyVo> getNetworkOrderModuleStat(Long networkId, NetworkOrderStatSelectVo selectVo);

    /**
     * 获取服务人员移动端创建工单统计数量
     * @param networkId 服务商ID
     * @param selectVo 搜索条件
     * @return
     */
    List<DateQtyVo> getNetworkMobileCreateOrderStat(Long networkId, NetworkOrderStatSelectVo selectVo);

    /**
     * 获取服务人员移动端工单结单统计数量
     * @param networkId 服务商ID
     * @param selectVo 搜索条件
     * @return
     */
    List<DateQtyVo> getNetworkMobileFinishOrderStat(Long networkId, NetworkOrderStatSelectVo selectVo);


    /**
     * 获取排行榜数据
     * @param networkId 服务商ID
     * @param selectVo 搜索条件
     * @return
     */
    List<QtyVo> getNetworkFinishOrderScoreStat(Long networkId, NetworkOrderStatSelectVo selectVo);

    /**
     * 获取服务商移动端消息工单列表
     * @param networkId 服务商ID
     * @param networkEmpId 工程师ID
     * @param selectVo 搜索条件
     * @return
     */
    List<WorkOrderExtend> getNetworkMobileOrderMessageList(Long networkId, Long networkEmpId, NetworkMobileOrderMessageListSelectVo selectVo);

    /**
     * 获取服务商移动端消息工单列表总记录数
     * @param networkId 服务商ID
     * @param networkEmpId 工程师ID
     * @param selectVo 搜索条件
     * @return
     */
    long getNetworkMobileOrderMessageListCount(Long networkId, Long networkEmpId, NetworkMobileOrderMessageListSelectVo selectVo);

    /**
     * 根据服务商ID&服务商人员ID获取服务人员的工单数量
     * @param networkId 服务商数量
     * @param networkEmpIds 服务商人员ID
     * @return
     */
    List<QtyVo> getNetworkEmpOrderQtyByNetworkAndNetworkEmpIds(Long networkId, List<Long> networkEmpIds);

    /**
     * 根据服务商搜索条件获取工单ID
     * @param custAccId 商家ID
     * @param networkId 服务商ID
     * @param networkEmpId 服务人员ID
     * @param keyword 搜索关键词：工单单号/一物一码/产品名称/产品型号
     * @return
     */
    List<Long> getWorkIdByNetworkOrderMobileSearch(Long custAccId, Long networkId, Long networkEmpId, String keyword);

    /**
     * 根据工单ID更新新进展或待处理事件数量
     * @param id 工单ID
     * @param newAdvance 新进展数量
     * @param waitCopeEvent 待处理数量
     */
    void updateNewAdvanceOrWaitCopeEventById(Long id, Integer newAdvance, Integer waitCopeEvent);

    /**
     * 根据工单ID获取工单导出字段
     * @param ids 工单ID
     * @param orderBy
     * @return
     */
    List<WorkOrderExtend> getOrderExportFieldByIds(List<Long> ids, String orderBy);

    /**
     * 根据[服务商ID] & [服务人员ID]获取今日完成工单量
     * @param custAccId 商家ID
     * @param networkId 服务商ID
     * @param networkEmpId 服务人员ID
     * @return
     */
    long getTodayFinishOrderQty(Long custAccId, Long networkId, Long networkEmpId);

    /**
     * 获取服务商移动端总工单数量
     * @param custAccId 商家ID
     * @param networkId 服务商ID
     * @param networkEmpId 工程师ID
     * @param selectVo 搜索对象
     * @return
     */
    long getNetworkMobileTotalOrderQty(Long custAccId, Long networkId, Long networkEmpId, NetworkOrderStatSelectVo selectVo);

    /**
     * 获取服务商移动端完成工单数量
     * @param custAccId 商家ID
     * @param networkId 服务商ID
     * @param networkEmpId 工程师ID
     * @param selectVo 搜索对象
     * @return
     */
    long getNetworkMobileFinishOrderQty(Long custAccId, Long networkId, Long networkEmpId, NetworkOrderStatSelectVo selectVo);

    /**
     * 获取服务商近七天(含今天)的工单数
     * @param custAccId 商家ID
     * @param networkId 服务商ID
     * @param networkEmpId 服务商人员ID
     * @return
     */
    List<DateQtyVo> getNetworkInSevenDaysOrder(Long custAccId, Long networkId, Long networkEmpId);

    /**
     * 根据改派工单ID更新工单信息
     * @param loginInfo
     * @param workId 工单ID
     * @param status 工单状态
     * @param networkId 服务商ID
     * @param networkEmpId 服务工程师ID
     * @param modulePrice 模块费用
     * @param totalPrice 总费用
     * @param payPrice 支付费用
     */
    void updateByChangeNetwork(AccounLoginInfo loginInfo, Long workId, Integer status, Long networkId, Long networkEmpId, BigDecimal modulePrice, BigDecimal totalPrice, BigDecimal payPrice);

    /**
     * 获取待审核的工单事件
     * @param workId 工单ID
     * @return
     */
    List<WorkWaitCheckOrderEvent> getWaitCheckOrderEventByWorkId(Long workId);

    /**
     * 获取商家详情之工单列表
     * @param factoryId 品牌商家ID
     * @param pageUtil 分页对象
     * @return
     */
    List<WorkOrderExtend> getFactoryDetailOrderList(Long factoryId, PageUtil pageUtil);

    /**
     * 获取商家详情之工单列表总记录数
     * @param factoryId 品牌商家ID
     * @return
     */
    long getFactoryDetailOrderListCount(Long factoryId);

    /**
     * 根据品工单ID获取工单所有费用(含：结算、工单服务费、工单配件费)
     * @param id 工单ID
     * @return
     */
    BigDecimal getFactoryAllFeeById(Long id);

    /**
     * 根据品工单ID获取工单所有费用(含：结算、工单服务费、工单配件费)
     * @param ids 工单ID
     * @return
     */
    List<ZjWorkOrder> getFactoryAllFeeByIds(List<Long> ids);

    /**
     * 查询重复工单并返回工单ID
     * @param custAccId 商家ID
     * @param search 重复工单查询条件
     * @return
     */
    List<Long> getWorkRepeat(Long custAccId, WorkRepeatSearchVo search);

    /**
     * 获取服务商移动端工单记录
     * @param networkId 服务商ID
     * @param networkEmpId 服务商人员ID
     * @param search
     * @return
     */
    List<ZjWorkOrder> getMobileWithdrawOrderRecord(Long networkId, Long networkEmpId, NetworkOrderRecordSearchVo search);

    /**
     * 获取服务商移动端工单记录总记录数
     * @param networkId 服务商ID
     * @param networkEmpId 服务商人员ID
     * @param search
     * @return
     */
    long getMobileWithdrawOrderRecordCount(Long networkId, Long networkEmpId, NetworkOrderRecordSearchVo search);

    /**
     * 根据工单ID获取服务商的所有费用
     * @param workIds 工单ID
     * @return
     */
    List<QtyVo> getNetworkTotalFee(List<Long> workIds);

    /**
     * 根据工单ID获取服务商的所有费用
     * @param workId 工单ID
     * @return
     */
    QtyVo getNetworkTotalFeeById(Long workId);

    /**
     * 获取工单记录详情
     * @param workId 工单ID
     * @return
     */
    ZjWorkOrder getWithdrawOrderRecordDetail(Long workId);

    /**
     * 可提现工单列表
     * @param networkId 服务商ID
     * @param networkEmpId 服务人员ID
     * @param search 搜索对象
     * @return
     */
    List<WorkOrderExtend> getWithdrawOrderList(Long networkId, Long networkEmpId, NetworkOrderRecordSearchVo search);

    /**
     * 可提现工单列表总记录数
     * @param networkId 服务商ID
     * @param networkEmpId 服务人员ID
     * @param search 搜索对象
     * @return
     */
    long getWithdrawOrderListCount(Long networkId, Long networkEmpId, NetworkOrderRecordSearchVo search);

    /**
     * 根据服务商ID & 服务人员ID获取可提现金额
     * @param networkId 服务商ID
     * @param networkEmpId 服务人员ID
     * @return
     */
    BigDecimal getNetworkWithdrawMoney(Long networkId, Long networkEmpId);

    /**
     * 根据服务商ID & 服务人员ID获取冻结金额
     * @param networkId 服务商ID
     * @param networkEmpId 服务人员ID
     * @return
     */
    BigDecimal getNetworkFreezeMoney(Long networkId, Long networkEmpId);

    /**
     * 查询工单单号是否重复
     * @param custAccId 商家ID
     * @param workNo 工单单号
     * @return
     */
    Integer existCodeByCustAccId(Long custAccId, String workNo);

    /**
     * 根据工单ID获取工单结算价
     * @param workIds 工单ID
     * @return
     */
    List<OrderSettlementPriceVo> getOrderSettlementPriceByWorkId(List<Long> workIds);

    /**
     * 根据工单ID获取工单结算价
     * @param workId 工单ID
     * @return
     */
    OrderSettlementPriceVo getOrderSettlementPriceByWorkId(Long workId);

    Boolean QualityAccId (Long custAccId);

    void updateInfo(OrderVo orderVo, AccounLoginInfo loginInfo);
}
